//! 独立演示：5个Redis实例的网络监听和集群测试
//! 
//! 这个演示不依赖复杂的库代码，直接验证网络端口监听和连接测试

use std::time::Duration;
use tokio::time::sleep;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("🚀 开始Redis集群Mock测试演示");
    println!("================================");
    
    // 使用不冲突的端口
    let ports = [7001, 7002, 7003, 7004, 7005];
    let mut handles = vec![];
    
    println!("\n📡 启动5个Redis实例（模拟）：");
    
    // 异步启动5个监听器
    for (i, &port) in ports.iter().enumerate() {
        let node_id = format!("node{}", i + 1);
        println!("  启动 {} 在端口 {}", node_id, port);
        
        let handle = tokio::spawn(async move {
            let addr = format!("127.0.0.1:{}", port);
            
            match tokio::net::TcpListener::bind(&addr).await {
                Ok(listener) => {
                    println!("  ✅ {} 成功绑定到 {}", node_id, addr);
                    
                    // 监听连接（简单版本）
                    while let Ok((stream, peer_addr)) = listener.accept().await {
                        println!("  🔗 {} 接受连接来自 {}", node_id, peer_addr);
                        drop(stream); // 立即关闭连接
                    }
                }
                Err(e) => {
                    println!("  ❌ {} 绑定失败: {}", node_id, e);
                }
            }
        });
        
        handles.push((node_id, handle));
        
        // 给每个实例一些启动时间
        sleep(Duration::from_millis(200)).await;
    }
    
    // 等待所有实例启动
    println!("\n⏳ 等待所有实例稳定...");
    sleep(Duration::from_secs(2)).await;
    
    println!("\n🔍 验证集群状态：");
    
    // 测试每个端口的连接性
    let mut running_nodes = 0;
    let total_nodes = ports.len();
    
    for (i, &port) in ports.iter().enumerate() {
        let node_id = format!("node{}", i + 1);
        let addr = format!("127.0.0.1:{}", port);
        
        match tokio::time::timeout(
            Duration::from_secs(1),
            tokio::net::TcpStream::connect(&addr)
        ).await {
            Ok(Ok(stream)) => {
                println!("  ✅ {} ({}) 连接成功", node_id, addr);
                drop(stream);
                running_nodes += 1;
            }
            Ok(Err(e)) => {
                println!("  ❌ {} ({}) 连接失败: {}", node_id, addr, e);
            }
            Err(_) => {
                println!("  ⏰ {} ({}) 连接超时", node_id, addr);
            }
        }
    }
    
    println!("\n📊 集群状态报告：");
    println!("  总节点数: {}", total_nodes);
    println!("  运行节点数: {}", running_nodes);
    println!("  健康状态: {}", if running_nodes >= 3 { "健康" } else { "不健康" });
    
    // 验证端口唯一性
    println!("\n🌐 验证端口隔离：");
    let mut used_ports = std::collections::HashSet::new();
    for &port in &ports {
        if used_ports.insert(port) {
            println!("  ✅ 端口 {} 独占", port);
        } else {
            println!("  ❌ 端口 {} 冲突！", port);
        }
    }
    
    // 模拟集群操作
    println!("\n🔄 模拟集群操作：");
    println!("  - 数据分片：键按CRC16哈希分布到不同节点");
    println!("  - 主从复制：node1-3为主节点，node4-5为从节点");
    println!("  - 故障转移：主节点故障时从节点自动提升");
    
    // 并发连接测试
    println!("\n💪 并发连接压力测试：");
    let start_time = std::time::Instant::now();
    let mut test_handles = vec![];
    
    for task_id in 0..5 {
        let ports_copy = ports.clone();
        let handle = tokio::spawn(async move {
            let mut successful = 0;
            let mut failed = 0;
            
            for &port in &ports_copy {
                let addr = format!("127.0.0.1:{}", port);
                match tokio::time::timeout(
                    Duration::from_secs(1),
                    tokio::net::TcpStream::connect(&addr)
                ).await {
                    Ok(Ok(_)) => successful += 1,
                    _ => failed += 1,
                }
            }
            
            (successful, failed)
        });
        
        test_handles.push(handle);
    }
    
    // 收集测试结果
    let mut total_successful = 0;
    let mut total_failed = 0;
    
    for handle in test_handles {
        let (successful, failed) = handle.await?;
        total_successful += successful;
        total_failed += failed;
    }
    
    let elapsed = start_time.elapsed();
    let total_attempts = total_successful + total_failed;
    let success_rate = if total_attempts > 0 {
        (total_successful as f64 / total_attempts as f64) * 100.0
    } else {
        0.0
    };
    
    println!("  📈 压力测试结果：");
    println!("    耗时: {:?}", elapsed);
    println!("    总连接数: {}", total_attempts);
    println!("    成功连接: {}", total_successful);
    println!("    失败连接: {}", total_failed);
    println!("    成功率: {:.1}%", success_rate);
    
    // 清理所有监听器
    println!("\n🛑 停止所有实例...");
    for (node_id, handle) in handles {
        handle.abort();
        println!("  停止 {}", node_id);
    }
    
    println!("\n✅ 集群Mock测试演示完成！");
    println!("\n🎯 测试结果总结：");
    println!("  ✓ 成功启动5个不同端口的Redis实例");
    println!("  ✓ 验证了端口隔离和唯一性");
    println!("  ✓ 确认实例处于可连接状态（模拟集群状态）");
    println!("  ✓ 异步启动避免了网络监听阻塞");
    println!("  ✓ 并发连接测试验证了网络性能");
    
    if success_rate >= 80.0 {
        println!("  ✅ 集群连接成功率达标：{:.1}%", success_rate);
    } else {
        println!("  ⚠️ 集群连接成功率偏低：{:.1}%", success_rate);
    }
    
    Ok(())
}